package com.zeny.express.framework.webapp.excel;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import com.zeny.express.framework.shared.util.DateUtils;
import com.zeny.express.framework.shared.util.UUIDUtils;
import com.zeny.express.framework.webapp.domain.ExportParams;


public class ExcelExporter {

	public void exportToFile(ExportParams params) throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		String fileName = UUIDUtils.getTimeUUID();
		File file = File.createTempFile(fileName, ExportParams.EXCEL_EXTENTION);
		
		Workbook workbook = new SXSSFWorkbook();
		
		Sheet sheet = workbook.createSheet(params.getSheetName());

		// write title
		this.writeTitle(workbook, sheet, params);
		
		// write rows
		this.writeRows(workbook, sheet, params);
		
		FileOutputStream fos = new FileOutputStream(file);
		workbook.write(fos);
		fos.close();
		
		params.setFile(file);
	}
	
	private void writeTitle(Workbook workbook, Sheet sheet, ExportParams params) {
		
		Row titleRow = sheet.createRow(0);
		CellStyle titleStyle = workbook.createCellStyle();
        Font titleFont = workbook.createFont();
        titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        titleStyle.setFont(titleFont);
        
		titleRow.setRowStyle(titleStyle);
		
		for (int j = 0; j < params.getColModelList().size(); ++j) {
			Cell cell = titleRow.createCell(j);
			GridModel model = params.getColModelList().get(j);
			cell.setCellValue(model.getLabel());
			cell.setCellStyle(titleStyle);
			if (NumberUtils.isDigits(model.getWidth())) {
				sheet.setColumnWidth(j, NumberUtils.createInteger(model.getWidth()) * 42);
			}
		}
		
	}

	private void writeRows(Workbook workbook, Sheet sheet, ExportParams params) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		
		List<?> datas = params.getPage().getRows();
		List<GridModel> models = params.getColModelList();
		for (int i = 0; i < datas.size(); ++i) {
			Object data = datas.get(i);
			
			Row row = sheet.createRow(i + 1);
			
			for (int j = 0; j < models.size(); ++j) {
				Cell cell = row.createCell(j);

				Object value = PropertyUtils.getProperty(data, models.get(j).getName());
				if (value == null) {
					continue;
				}
				
				if ("date".equalsIgnoreCase(models.get(j).getFormatter())) {
					
					if (models.get(j).getFormatoptions() != null && StringUtils.isNotEmpty(models.get(j).getFormatoptions().getNewformat())) {
						cell.setCellValue(DateUtils.format((Date) value, models.get(j).getFormatoptions().getNewformat()));
					} else {
						cell.setCellValue(DateUtils.format((Date) value));
					}
					
				} else {
					cell.setCellValue(ObjectUtils.toString(value));
				}
			}
			
		}
		
	}
	
}
